using System;
using System.Windows.Forms;

namespace Be.Timvw.Framework.Windows.Forms
{
    public partial class TypeTree : UserControl
    {
        public TypeTree()
        {
            this.InitializeComponent();
        }

        public virtual Type SelectedType
        {
            get { return this.treeViewTypes.SelectedNode == null ? null : this.treeViewTypes.SelectedNode.Tag as Type; }
            set
            {
                if(this.treeViewTypes.Nodes != null)
                {
                    foreach(TreeNode treeNode in this.treeViewTypes.Nodes)
                    {
                        if(treeNode.Tag == value)
                        {
                            this.treeViewTypes.SelectedNode = treeNode;
                            break;
                        }
                    }
                }
            }
        }

        public virtual void Clear()
        {
            if(this.treeViewTypes.Nodes != null)
            {
                this.treeViewTypes.Nodes.Clear();
            }
        }

        public virtual void LoadTypes(Type[] types)
        {
            if(types == null)
            {
                this.Clear();
            }
            else
            {
                if(this.treeViewTypes.Nodes != null)
                {
                    this.treeViewTypes.Nodes.Clear();

                    if(types.Length > 0)
                    {
                        Type[] sortedTypes = TypeHelper.Sort(types);

                        string currentAssembly = string.Empty;
                        TreeNode currentAssemblyNode = null;
                        string currentNamespace = string.Empty;
                        TreeNode currentNamespaceNode = null;

                        foreach(Type type in sortedTypes)
                        {
                            if(type.Assembly.FullName != currentAssembly)
                            {
                                currentAssembly = type.Assembly.FullName;
                                currentAssemblyNode = new TreeNode();
                                currentAssemblyNode.Text = type.Assembly.FullName;
                                currentAssemblyNode.ImageKey = currentAssemblyNode.SelectedImageKey = "module.gif";
                                this.treeViewTypes.Nodes.Add(currentAssemblyNode);

                                currentNamespace = string.Empty;
                                currentNamespaceNode = null;
                            }

                            if(type.Namespace != currentNamespace)
                            {
                                currentNamespace = type.Namespace;
                                currentNamespaceNode = new TreeNode();
                                currentNamespaceNode.Text = type.Namespace;
                                currentNamespaceNode.ImageKey = currentNamespaceNode.SelectedImageKey = "namespace.gif";
                                currentAssemblyNode.Nodes.Add(currentNamespaceNode);
                            }

                            TreeNode typeNode = new TreeNode();
                            typeNode.Text = type.Name;
                            typeNode.ImageKey = typeNode.SelectedImageKey = GetTypeImageKey(type);
                            typeNode.Tag = type;
                            currentNamespaceNode.Nodes.Add(typeNode);
                        }

                        this.treeViewTypes.TopNode = this.treeViewTypes.Nodes[0];
                        this.treeViewTypes.SelectedNode = this.treeViewTypes.Nodes[0];
                    }
                }
            }

            this.treeViewTypes.ExpandAll();
        }

        public static string GetTypeImageKey(Type type)
        {
            if(type.IsInterface)
            {
                return "interface.gif";
            }

            if(typeof(Enum).IsAssignableFrom(type))
            {
                return "enum.gif";
            }

            if(typeof(ValueType).IsAssignableFrom(type))
            {
                return "structure.gif";
            }

            return "class.gif";
        }
    }
}